package com.guilin.system.service.impl;

import com.guilin.common.core.domain.AjaxResult;
import com.guilin.common.core.domain.entity.SysUser;
import com.guilin.common.core.domain.model.LoginUser;
import com.guilin.common.exception.ServiceException;
import com.guilin.common.utils.DateUtils;
import com.guilin.common.utils.SecurityUtils;
import com.guilin.domain.Alumni;
import com.guilin.domain.ForumReply;
import com.guilin.mapper.AlumniMapper;
import com.guilin.mapper.ForumReplyMapper;
import com.guilin.system.mapper.SysUserMapper;
import com.guilin.system.service.ForumReplyService;
import com.guilin.system.service.ForumThreadService;
import com.guilin.vo.ForumReplyVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 论坛主题回复Service业务层处理
 * 
 * @author xiaoqi
 * @date 2025-06-20
 */
@Service
@Slf4j
public class ForumReplyServiceImpl implements ForumReplyService
{
    @Autowired
    private ForumReplyMapper forumReplyMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private AlumniMapper alumniMapper;

    @Autowired
    private ForumThreadService forumThreadService;

    /**
     * 查询论坛主题回复
     * 
     * @param id 论坛主题回复主键
     * @return 论坛主题回复
     */
    @Override
    public ForumReply selectForumReplyById(Long id)
    {
        return forumReplyMapper.selectForumReplyById(id);
    }


    /**
     * 查询论坛主题回复列表
     * 
     * @param forumReply 论坛主题回复
     * @return 论坛主题回复
     */
    @Override
    public List<ForumReplyVO> selectForumReplyList(ForumReply forumReply)
    {
        // 普通列表查询（平铺结构）
        return forumReplyMapper.selectForumReplyList(forumReply);
    }

    /**
     * 获取层级结构的回复列表
     * @param threadId
     * @return
     */
    public List<ForumReplyVO> getHierarchicalReplies(Long threadId) {

        // 调用Mapper方法获取层级结构的回复列表
        return forumReplyMapper.selectHierarchicalReplyList(threadId);
    }

    /**
     * 添加子回复
     * @param reply
     * @return
     */
    @Transactional
    public int addChildReply(ForumReply reply) {

        // 验证父回复是否存在
        ForumReply parent = forumReplyMapper.selectForumReplyById(reply.getParentId());
        if (parent == null || parent.getStatus() != 1) {
            throw new ServiceException("父回复不存在或已被删除");
        }

        // 设置主题ID与父回复一致
        reply.setThreadId(parent.getThreadId());

        // 设置当前用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        long userId = loginUser.getUser().getUserId();
        SysUser sysUser = sysUserMapper.selectUserById(userId);

        if (sysUser != null) {
            String userType = sysUser.getUserType();
            if ("admin".equals(userType)) {
                reply.setAdminId(userId);
            } else if ("alumni".equals(userType)) {
                Alumni alumni = alumniMapper.selectUserId(userId);
                if (alumni != null) {
                    reply.setAlumniId(alumni.getId());
                } else {
                    throw new ServiceException("未找到对应的校友记录");
                }
            } else {
                throw new ServiceException("用户类型错误");
            }
        } else {
            throw new ServiceException("用户信息不存在");
        }

        reply.setCreateTime(DateUtils.getNowDate());
        int result = forumReplyMapper.insertForumReply(reply);

        // 新增回复后，更新主题的回复数
        if (result > 0) {

            // 增加主题回复数
            forumThreadService.updateReplyCount(reply.getThreadId(), 1);

            // 更新父回复的最后回复时间
            ForumReply updateParent = new ForumReply();
            updateParent.setId(parent.getId());
            updateParent.setUpdateTime(DateUtils.getNowDate());
            forumReplyMapper.updateForumReply(updateParent);
        }


        return result;
    }

    /**
     * 新增论坛主题回复
     * 
     * @param forumReply 论坛主题回复
     * @return 结果
     */
    @Transactional
    public int insertForumReply(ForumReply forumReply)
    {
        // 获取当前登录用户的ID
        LoginUser loginUser = SecurityUtils.getLoginUser();
        long userId = loginUser.getUser().getUserId();

        // 根据用户ID查询用户信息
        SysUser sysUser = sysUserMapper.selectUserById(userId);

        if (sysUser != null) {
            String userType = sysUser.getUserType();

            // 判断当前用户类型
            if ("admin".equals(userType)) {
                // 管理员用户，直接设置admin_id
                forumReply.setAdminId(userId);
            } else if ("alumni".equals(userType)) {
                // 校友用户，需要查询alumni表获取正确的alumni_id
                Alumni alumni = alumniMapper.selectUserId(userId);
                if (alumni != null) {
                    forumReply.setAlumniId(alumni.getId());
                } else {

                    throw new ServiceException("用户类型错误，未找到对应的校友记录");
                }
            } else {

                throw new ServiceException("用户类型错误，仅支持管理员(admin)和校友(alumni)类型");
            }
        } else {
            throw new ServiceException("用户信息不存在");
        }

        forumReply.setCreateTime(DateUtils.getNowDate());
        int result = forumReplyMapper.insertForumReply(forumReply);

        // 新增回复后，更新主题的回复数
        if (result > 0) {

            // 增加主题回复数
            forumThreadService.updateReplyCount(forumReply.getThreadId(), 1);
        }

        return result;
    }

    /**
     * 修改论坛主题回复
     * 
     * @param forumReply 论坛主题回复
     * @return 结果
     */
    @Override
    public int updateForumReply(ForumReply forumReply)
    {
        forumReply.setUpdateTime(DateUtils.getNowDate());
        return forumReplyMapper.updateForumReply(forumReply);
    }

    /**
     * 批量删除论坛主题回复
     * 
     * @param ids 需要删除的论坛主题回复主键
     * @return 结果
     */
    @Transactional
    public int deleteForumReplyByIds(Long[] ids)
    {
        // 1. 预处理要删除的回复
        Map<Long, Integer> threadCountMap = new HashMap<>(); //存储主题ID与对应要删除的回复数
        List<Long> validIds = new ArrayList<>(); // 存储有效的回复ID（存在且未删除）

        for (Long id : ids) {
            ForumReply reply = forumReplyMapper.selectForumReplyById(id);

            // 只处理存在且状态为未删除(1)的回复
            if (reply != null && reply.getStatus() == 1) {
                Long threadId = reply.getThreadId();

                // 更新主题对应的删除回复数
                //getOrDefault(threadId, 0) 如果threadId已存在于 Map 中，返回其当前值；如果不存在，则返回默认值0
                threadCountMap.put(threadId, threadCountMap.getOrDefault(threadId, 0) + 1);

                // 记录有效的回复ID
                validIds.add(id);
            }
        }

        if (validIds.isEmpty()) {
            return 0;
        }

        // 批量删除回复
        int result = forumReplyMapper.deleteForumReplyByIds(validIds.toArray(new Long[0]));

        // 批量更新主题的回复数
        if (result > 0) {
            for (Map.Entry<Long, Integer> entry : threadCountMap.entrySet()) {
                Long threadId = entry.getKey();
                int count = entry.getValue();
                forumThreadService.updateReplyCount(threadId, -count);
            }
        }
        return result;
    }

    /**
     * 删除论坛主题回复信息
     * 
     * @param id 论坛主题回复主键
     * @return 结果
     */
    @Transactional
    public int deleteForumReplyById(Long id)
    {
        // 查询回复，获取主题ID
        ForumReply reply = forumReplyMapper.selectForumReplyById(id);

        if (reply == null) {
            return 0; // 回复不存在，直接返回
        }

        int result = forumReplyMapper.deleteForumReplyById(id);

        // 删除回复后，更新主题的回复数
        if (result > 0) {

            // 减少主题回复数
            forumThreadService.updateReplyCount(reply.getThreadId(), -1);
        }
        return result;
    }


    /**
     * 检查是否是回复的作者
     * @param reply
     * @param currentUserId
     * @return
     */
    public boolean isOwner(ForumReply reply, Long currentUserId) {

        // 判断回复是否存在
        if (reply == null) {
            return false;
        }

        // 管理员可以删除任何回复
        if (SecurityUtils.isAdminUser()) {
            return true;
        }

        // 校友用户只能删除自己的回复
        Alumni alumni = alumniMapper.selectUserId(currentUserId);
        return alumni != null && alumni.getId().equals(reply.getAlumniId());

    }
}
